package com.guguskins.back.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guguskins.back.common.constant.InventoryConstant;
import com.guguskins.back.common.exception.GlobalMsgException;
import com.guguskins.back.entity.*;
import com.guguskins.back.entity.vo.PageVo;
import com.guguskins.back.mapper.GuWithdrawalMapper;
import com.guguskins.back.service.*;
import com.guguskins.back.utils.CommonUtil;
import com.guguskins.back.utils.steam.Bot.SteamBotResponse;
import com.guguskins.back.utils.steam.SteamBotUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author mybatis-plus
 * @since 2021-08-02
 */
@Service
@Slf4j
public class GuWithdrawalServiceImpl extends ServiceImpl<GuWithdrawalMapper, GuWithdrawal> implements GuWithdrawalService {

    @Autowired
    private GuUserService userService;

    @Autowired
    private GuStockService stockService;

    @Autowired
    private GuBotService botService;

    @Autowired
    private GuInventoryService inventoryService;

    @Override
    public PageVo<GuWithdrawal> backPage(int p, int size, String searchKey) {
        IPage<GuWithdrawal> page = new Page<>(p, size);
        page = this.page(page, new LambdaQueryWrapper<GuWithdrawal>() {
            {
                like(!ObjectUtils.isEmpty(searchKey), GuWithdrawal::getWithdrawalUid, searchKey);
                or();
                like(!ObjectUtils.isEmpty(searchKey), GuWithdrawal::getWithdrawalUserSteamId, searchKey);
                or();
                like(!ObjectUtils.isEmpty(searchKey), GuWithdrawal::getWithdrawalUserNickname, searchKey);
                or();
                like(!ObjectUtils.isEmpty(searchKey), GuWithdrawal::getWithdrawalBotSteamId, searchKey);
            }
        });
        List<GuWithdrawal> records = page.getRecords();
        records.forEach(record -> {
            if (!ObjectUtils.isEmpty(record.getWithdrawalMyItems())) {
                GuStock stock = JSON.parseObject(record.getWithdrawalMyItems(), GuStock.class);
                record.setStockMarketName(stock.getStockMarketName());
            }
        });
        return new PageVo<>(records, page.getTotal());
    }

    @Override
    public boolean trade(GuUser user, Long inventoryId, String itemName) {
        List<GuStock> stocks = stockService.list(new LambdaQueryWrapper<GuStock>() {
            {
                eq(GuStock::getStockMarketName, itemName);
            }
        });
        List<GuBot> bots = botService.getList();
        GuStock stock = new GuStock();
        label:
        for (GuStock guStock : stocks) {
            for (GuBot guBot : bots) {
                if (!ObjectUtils.isEmpty(guBot.getBotSteamId()) && guBot.getBotSteamId().equals(guStock.getStockSteamId()) && guBot.getBotEnable() && guBot.getBotOnline()) {
                    stock = guStock;
                    break label;
                }
            }
        }
        if (ObjectUtils.isEmpty(stock)) {
            return false;
        }
        //发起交易
        GuWithdrawal withdrawal = new GuWithdrawal();
        withdrawal.setWithdrawalUid(CommonUtil.generateRandomStr());
        withdrawal.setWithdrawalBotSteamId(stock.getStockSteamId());
        withdrawal.setWithdrawalUserId(user.getUserId());
        withdrawal.setWithdrawalUserSteamId(user.getUserSteamId());
        withdrawal.setWithdrawalUserNickname(user.getUserNickname());
        withdrawal.setWithdrawalInventoryId(inventoryId);
        withdrawal.setWithdrawalMyItems(JSON.toJSONString(stock));
        withdrawal.setStock(stock);
        withdrawal.setWithdrawalTradeurl(user.getUserTradingUrl());
        withdrawal.setWithdrawalCancelTime(600000L);

        JSONObject jsonObject = this.initTrade(withdrawal);

        if (withdrawal.insert()) {
            SteamBotResponse steamBotResponse = SteamBotUtil.trade(jsonObject);
            if (!steamBotResponse.getCode().equals(0)) {
                log.error("海盗海添加账号失败：{}", steamBotResponse.getMessage());
                throw new GlobalMsgException("更新账号失败");
            }
            withdrawal.setWithdrawalState(1);
            return withdrawal.updateById();
        }
        return false;
    }

    @Override
    public boolean callback(JSONObject jsonObject) {
        String uid = jsonObject.getJSONObject("body").getString("uid");
        GuWithdrawal withdrawal = this.getOne(new LambdaQueryWrapper<GuWithdrawal>() {
            {
                eq(GuWithdrawal::getWithdrawalUid, uid);
            }
        });
        if (ObjectUtils.isEmpty(withdrawal)) {
            return false;
        }
        withdrawal.setWithdrawalBotMessage(jsonObject.getString("bot_message"));
        withdrawal.setWithdrawalState(jsonObject.getInteger("state"));

        return withdrawal.updateById();
    }

    @Override
    public boolean backCancel(GuWithdrawal withdrawal) {
        GuWithdrawal guWithdrawal = this.getById(withdrawal.getWithdrawalId());
        String uid = guWithdrawal.getWithdrawalUid();
        SteamBotUtil.canceltrade(uid);

        GuInventory inventory = inventoryService.getById(withdrawal.getWithdrawalInventoryId());
        inventory.setInventoryState(InventoryConstant.State.INVENTORY);

        return inventory.updateById();
    }

    private JSONObject initTrade(GuWithdrawal withdrawal) {
        JSONObject item = new JSONObject();
        GuStock stock = withdrawal.getStock();
        item.put("appid", stock.getStockAppId());
        item.put("contextid", stock.getStockContextId());
        item.put("assetid", stock.getStockAssetId());
        JSONArray items = new JSONArray();
        items.add(item);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("steamId", withdrawal.getWithdrawalBotSteamId());
        jsonObject.put("my_items", items);
        jsonObject.put("tradeurl", withdrawal.getWithdrawalTradeurl());
        jsonObject.put("cancel_time", withdrawal.getWithdrawalCancelTime());
        jsonObject.put("uid", withdrawal.getWithdrawalUid());
        return jsonObject;
    }
}
